﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel.Syndication;
using AutoMapper;
using HelperTools;
using Interfaces.Models;
using NewsDataProvider.DataContainers;

namespace NewsDataProvider.Mapping
{
    public static class SyndicationItemMappingCreator
    {
        private static void CreateMap()
        {
            Mapper.Reset();
            Mapper.CreateMap<SyndicationLink, ILink>()
                  .ForMember(src => src.Id, opt => opt.ResolveUsing(x => Guid.NewGuid()))
                  .ForMember(src => src.Url, opt => opt.MapFrom(dst => dst.Uri.AbsoluteUri))
                  .ConstructUsing((Func<ResolutionContext, ILink>) (obj => new LinkContainer()));
            Mapper.CreateMap<SyndicationPerson, IPerson>()
                .ForMember(src=>src.Id, opt=>opt.ResolveUsing(x=>Guid.NewGuid()))
                .ConstructUsing((Func<ResolutionContext, IPerson>)(obj => new PersonDataContainer()));
            Mapper.CreateMap<SyndicationCategory, ICategory>()
                .ForMember(src => src.Id, opt => opt.ResolveUsing(x => Guid.NewGuid()))
                .ConstructUsing((Func<ResolutionContext, ICategory>)(obj => new CategoryDataContainer()));
            Mapper.CreateMap<SyndicationItem, INewsDataItem>()
                  .ConstructUsing((Func<ResolutionContext, INewsDataItem>)(obj => new NewsItemDataContainer()))
                  .ForMember(src => src.Id, opt => opt.ResolveUsing(x => Guid.NewGuid()))
                  .ForMember(dest => dest.BaseUri, opt => opt.MapFrom(src => src.BaseUri.With(x => x.AbsoluteUri)))
                  .ForMember(dest => dest.Links,opt => opt.ResolveUsing(x=>Mapper.Map<IEnumerable<SyndicationLink>,IEnumerable<ILink>>(x.Links)))
                  .ForMember(dest => dest.Persons, opt => opt.ResolveUsing(x => Mapper.Map< IEnumerable<SyndicationPerson>, IEnumerable<IPerson>>(x.Authors.Union(x.Contributors))))
                  .ForMember(dest => dest.Copyright, opt => opt.MapFrom(src => src.Copyright.With(cop => cop.Text)))
                  .ForMember(dest => dest.Content, opt => opt.MapFrom(src => src.Content.With(cop => cop.Type)))
                  .ForMember(dest => dest.Title, opt => opt.MapFrom(src => src.Title.With(cop => cop.Text)))
                  .ForMember(dest => dest.Summary, opt => opt.MapFrom(src => src.Summary.With(cop => cop.Text)))
                  .ForMember(dest => dest.PublishDate, opt => opt.MapFrom(src => src.PublishDate.DateTime))
                  .ForMember(dest => dest.LastUpdatedTime, opt => opt.MapFrom(src => src.LastUpdatedTime.DateTime));
            Mapper.CreateMap<SyndicationFeed, IFeed>()
                  .ForMember(src => src.Id, opt => opt.ResolveUsing(x => Guid.NewGuid()))
                  .ConstructUsing((Func<ResolutionContext, IFeed>)(obj => new FeedDataContainer()))
                   .ForMember(dest => dest.Persons, opt => opt.ResolveUsing(x => Mapper.Map<IEnumerable<SyndicationPerson>, IEnumerable<IPerson>>(x.Authors.Union(x.Contributors))))
                  .ForMember(dest => dest.ImageUrl, opt => opt.MapFrom(src => src.ImageUrl.With(x => x.AbsolutePath)))
                  .ForMember(dest => dest.BaseUri, opt => opt.MapFrom(src => src.BaseUri.With(x => x.AbsoluteUri)))
                  .ForMember(dest => dest.Links, opt => opt.ResolveUsing(x => Mapper.Map<IEnumerable<SyndicationLink>, IEnumerable<ILink>>(x.Links)))
                  .ForMember(dest => dest.Copyright, opt => opt.MapFrom(src => src.Copyright.With(cop => cop.Text)))
                  .ForMember(dest => dest.Description,opt => opt.MapFrom(src => src.Description.With(desc => desc.Text)))
                  .ForMember(dest => dest.LastUpdatedTime, opt => opt.MapFrom(src => src.LastUpdatedTime.DateTime))
                  .ForMember(dest => dest.Title, opt => opt.MapFrom(src => src.Title.With(cop => cop.Text)))
                  .ForMember(dest => dest.Language, opt => opt.MapFrom(src => src.Language));
        }

        public static void Init()
        {
            CreateMap();
        }
    }
}
